package com.bkhech.controller;


import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import com.bkhech.RequestConstant;
import com.bkhech.enums.PlatformEnum;
import com.bkhech.excptions.GraceException;
import com.bkhech.grace.result.GraceJSONResult;
import com.bkhech.grace.result.ResponseStatusEnum;
import com.bkhech.pojo.Users;
import com.bkhech.pojo.bo.RegistryLoginBO;
import com.bkhech.pojo.vo.UsersVO;
import com.bkhech.service.UsersService;
import com.bkhech.tasks.SmsTask;
import com.bkhech.utils.IPUtil;
import com.bkhech.utils.RedisOperator;
import com.bkhech.utils.UserTokenUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/passport")
public class PassportController {

    @Resource
    private RedisOperator redisOperator;

    @Resource
    private SmsTask smsTask;
    @Resource
    private UsersService usersService;
    @Resource
    private HttpServletRequest request;

    @GetMapping("/getSMSCode")
    public GraceJSONResult smsTask(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return GraceJSONResult.error();
        }

        String userIP = IPUtil.getRequestIp(request);
        String redisUserIPKey = StrUtil.join(":", "mobile", "smscode", userIP);
        //限制该用户的 手机号/ip 在 60s 内只能获得一次验证码
        redisOperator.setnx60s(redisUserIPKey, mobile);
//        String code = (int)((Math.random() * 9 + 1) * 100000) + "";
        // 模拟发送短信验证码，默认值 123456
        String code = "123456";
        smsTask.sendSms(mobile, code);

        String redisKey = StrUtil.join(":", "mobile", "smscode", mobile);
        redisOperator.set(redisKey, code, 5 * 60);

        return GraceJSONResult.ok();
    }

    @PostMapping("/registry")
    public GraceJSONResult<UsersVO> registry(@RequestBody @Valid RegistryLoginBO registryLoginBO) {
        String mobile = registryLoginBO.getMobile();
        String smsCode = registryLoginBO.getSmsCode();
        String redisKey = StrUtil.join(":", "mobile", "smscode", mobile);
        String smsCodeVal = redisOperator.get(redisKey);
        if (StringUtils.isBlank(smsCodeVal) || !smsCodeVal.equalsIgnoreCase(smsCode)) {
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }

        Users users = usersService.queryMobileIfExist(mobile);
        if (users != null) {
            GraceJSONResult.errorCustom(ResponseStatusEnum.USER_ALREADY_EXIST_ERROR);
        }

        users = usersService.createUsers(mobile, registryLoginBO.getNickname());
        // 注册成功后，删除 redis 中的短信验证码使其失效
        redisOperator.del(redisKey);
        String redisUserIPKey = StrUtil.join(":", "mobile", "smscode", IPUtil.getRequestIp(request));
        redisOperator.del(redisUserIPKey);

        // 生成令牌
        UsersVO usersVO = buildUserToken(users);
        return GraceJSONResult.ok(usersVO);
    }

    @PostMapping("/login")
    public GraceJSONResult<UsersVO> login(@RequestBody @Valid RegistryLoginBO registryLoginBO) {
        String mobile = registryLoginBO.getMobile();
        String smsCode = registryLoginBO.getSmsCode();

        String redisKey = StrUtil.join(":", "mobile", "smscode", mobile);
        String smsCodeVal = redisOperator.get(redisKey);
        if (StringUtils.isBlank(smsCodeVal) || !smsCodeVal.equalsIgnoreCase(smsCode)) {
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }

        Users users = usersService.queryMobileIfExist(mobile);
        if (users == null) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }
        // 登录成功后，删除 redis 中的短信验证码使其失效
        redisOperator.del(redisKey);
        String redisUserIPKey = StrUtil.join(":", "mobile", "smscode", IPUtil.getRequestIp(request));
        redisOperator.del(redisUserIPKey);

        // 生成令牌
        UsersVO usersVO = buildUserToken(users);
        return GraceJSONResult.ok(usersVO);
    }


    @PostMapping("/logout")
    public GraceJSONResult<Void> logout(HttpServletRequest request) {
        String userToken = request.getHeader(RequestConstant.HEADER_USER_TOKEN);
        UserTokenUtil.removeToken(userToken);
        return GraceJSONResult.ok();
    }


    /**
     * 生成用户令牌
     *
     * @param users
     * @return
     */
    private UsersVO buildUserToken(Users users) {
        final String userToken = UserTokenUtil.setToken(users.getId(), PlatformEnum.TOKEN_APP_PREFIX);
        UsersVO usersVO = new UsersVO();
        usersVO.setUserToken(userToken);
        BeanUtils.copyProperties(users, usersVO);
        return usersVO;
    }
}
